package im.composer.audioservers.aggr;

import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

import org.jaudiolibs.audioservers.AudioClient;
import org.jaudiolibs.audioservers.AudioConfiguration;

public class DelegatedClient implements AudioClient {

	private final AggregateAudioServer parent;
	private AudioConfiguration context = null;
	List<FloatBuffer> inputs;
	List<FloatBuffer> outputs;

	public DelegatedClient(AggregateAudioServer parent) {
		this.parent = parent;
	}

	@Override
	public void configure(AudioConfiguration context) throws Exception {
		if (context == null) {
			throw new NullPointerException();
		}
		this.context = context;
		allocateBuffers();
		parent.notifyChanges();
	}

	private void allocateBuffers() {
		inputs = new ArrayList<>(context.getInputChannelCount());
		for (int i = 0; i < context.getInputChannelCount(); i++) {
			inputs.add(FloatBuffer.allocate(context.getMaxBufferSize()));
		}
		outputs = new ArrayList<>(context.getOutputChannelCount());
		for (int i = 0; i < context.getOutputChannelCount(); i++) {
			outputs.add(FloatBuffer.allocate(context.getMaxBufferSize()));
		}
	}

	public AudioConfiguration getAudioContext() {
		return context;
	}

	@Override
	public boolean process(long time, List<FloatBuffer> inputs, List<FloatBuffer> outputs, int nframes) {
		doInput(inputs);
		parent.exchangeData(this);
		doOutput(outputs);
		return parent.isActive();
	}

	private void doInput(List<FloatBuffer> inputs) {
		for (int i = 0; i < inputs.size(); i++) {
			float[] arr = inputs.get(i).array();
			this.inputs.set(i, FloatBuffer.wrap(arr));
		}
	}

	private void doOutput(List<FloatBuffer> outputs) {
		for (int i = 0; i < outputs.size(); i++) {
			float[] arr = this.outputs.get(i).array();
			outputs.set(i, FloatBuffer.wrap(arr));
		}
	}

	@Override
	public void shutdown() {

	}

}
